﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace sBlog.Net.Memcache
{
    public class MemcachedProvider : CachingProvider, IDisposable
    {
        private long defaultExpireTime;
        private string keySuffix;
        private static MemcachedClient mc;

        public MemcachedProvider(string configFile)
        {
            Initialize(configFile);
        }

        public void Dispose()
        {
            mc = null;
        }

        private void Initialize(string configFile)
        {
            XmlNode node = MemcachedConfig.GetConfigSection(configFile, "YanMlog/MemCached");

            DefaultExpireTime = Convert.ToInt32(node.Attributes["defaultExpireTime"].Value);
            KeySuffix = Convert.ToString(node.Attributes["keySuffix"].Value);
            string servers = Convert.ToString(node.Attributes["servers"].Value);

            if (mc == null)
            {
                if (servers != "")
                {
                    if (servers.IndexOf(",") > 0)
                    {
                        MemcachedClient.Setup("mycachingclient", servers.Split(','));
                        mc = MemcachedClient.GetInstance("mycachingclient");
                        mc.KeyPrefix = KeySuffix;
                    }
                    else
                    {
                        MemcachedClient.Setup("mycachingclient", new string[] { servers });
                        mc = MemcachedClient.GetInstance("mycachingclient");
                        mc.KeyPrefix = KeySuffix;
                    }
                }
                else mc = null;
            }
        }

        public override long DefaultExpireTime
        {
            get { return defaultExpireTime; }
            set { defaultExpireTime = value; }
        }

        public override string KeySuffix
        {
            get { return keySuffix; }
            set { keySuffix = value; }
        }

        public override bool Add(string strKey, object objValue, bool bDefaultExpire)
        {
            bool retVal = false;
            if (mc != null)
            {
                strKey = strKey.ToLower().Replace(" ", "");
                if (bDefaultExpire)
                {
                    retVal = mc.Set(strKey, objValue, DateTime.Now.AddMilliseconds(DefaultExpireTime));
                }
                else
                {
                    retVal = mc.Set(strKey, objValue);
                }

            }
            else retVal = false;
            return retVal;
        }

        public override bool Add(string strKey, object objValue)
        {
            bool retVal = false;
            if (mc != null)
            {
                strKey = strKey.ToLower().Replace(" ", "");
                retVal = mc.Set(strKey, objValue);
            }
            else retVal = false;
            return retVal;
        }

        public override bool Add(string strKey, object objValue, long lNumOfMilliSeconds)
        {
            bool retVal = false;
            if (mc != null)
            {
                strKey = strKey.ToLower().Replace(" ", "");
                retVal = mc.Set(strKey, objValue, DateTime.Now.AddMilliseconds(lNumOfMilliSeconds));
            }
            else retVal = false;
            return retVal;
        }

        public override object Get(string strKey)
        {
            if (mc != null)
            {
                strKey = strKey.ToLower().Replace(" ", "");
                return mc.Get(strKey);
            }
            else return null;
        }

        public override bool RemoveAll()
        {
            bool retVal = false;
            if (mc != null)
                retVal = mc.FlushAll();
            else
                retVal = false;
            return retVal;
        }

        public override bool Remove(string strKey)
        {
            bool retVal = false;
            if (mc != null)
            {
                strKey = strKey.ToLower().Replace(" ", "");
                retVal = mc.Delete(strKey);
            }
            else
                retVal = false;
            return retVal;
        }

        public override ulong? Increment(string strKey, ulong lAmount)
        {
            if (mc != null)
            {
                strKey = strKey.ToLower().Replace(" ", "");
                return mc.Increment(strKey, (ulong)lAmount);
            }
            else return 0;
        }

        public override ulong? Decrement(string strKey, ulong lAmount)
        {
            if (mc != null)
            {
                strKey = strKey.ToLower().Replace(" ", "");
                return mc.Decrement(strKey, (ulong)lAmount);
            }
            else return 0;
        }

        public override string GetHostStatus()
        {
            string retVal = "";
            if (mc != null)
            {
                foreach (KeyValuePair<string, Dictionary<string, string>> host in mc.Status())
                {
                    retVal += host.Key + "<br/>";
                    foreach (KeyValuePair<string, string> item in host.Value)
                    {
                        retVal += item.Key + ": " + item.Value + "<br/>";
                    }
                }
            }
            else retVal = "";
            return retVal;
        }
    }
}
